package com.xunshibao.tutor.common;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.xunshibao.tutor.po.Area;
import com.xunshibao.tutor.po.Area.TYPE;

@Service
public class AreaServiceImpl {
	private Map<String, Area> provinceCache = new HashMap<String, Area>();
	private Map<String, Area> cityCache = new HashMap<String, Area>();
	private Map<String, Area> distinctCache = new HashMap<String, Area>();
	private String UNKNOWN = "unknown";

	@Autowired
	private AreaDaoImpl areaDao;

	public List<Area> getProvinces() {
		return areaDao.getAreaByType(Area.TYPE.PROVINCE);
	}

	public List<Area> getCities(Integer provinceId) {
		return areaDao.getAreaByTypeAndParentCode(Area.TYPE.CITY, provinceId);
	}

	public List<Area> getDistincts(Integer cityId) {
		return areaDao.getAreaByTypeAndParentCode(Area.TYPE.DISTINCT, cityId);
	}

	public String getArea(String code, Area.TYPE type) {
		Area area = null;
		switch (type) { 
		case PROVINCE:
			area = provinceCache.get(code);
			if (area == null) {
				area = getArea(Integer.valueOf(code), Area.TYPE.PROVINCE);
				if (area != null)
					provinceCache.put(area.getCode().toString(), area);
			}
			break;
		case CITY:
			area = cityCache.get(code);
			if (area == null) {
				area = getArea(Integer.valueOf(code), Area.TYPE.CITY);
				if (area != null)
					cityCache.put(area.getCode().toString(), area);
			}
			break;
		case DISTINCT: 
			area = distinctCache.get(code);
			if (area == null) {
				area = getArea(Integer.valueOf(code), Area.TYPE.DISTINCT);
				if (area != null)
					distinctCache.put(area.getCode().toString(), area);
			}
			break;

		default:
			break;
		}
		if (area != null)
			return area.getName();
		else
			return UNKNOWN;
	}

	private Pattern ptn = Pattern.compile("^(\\d+)(:\\d+){1,2}$");

	/**
	 * parse PROVINCE:CITY:DISTINCT code to names.
	 * 
	 * @param areaInfo
	 * @return
	 */
	public String pareArea(String areaInfo) { 
		if (areaInfo != null) {
			Matcher m = ptn.matcher(areaInfo);
			if (m.find()) {
				StringBuilder areaBuffer = new StringBuilder();
				String[] areas = areaInfo.split(":");
				areaBuffer.append(getArea(areas[0], TYPE.PROVINCE));
				areaBuffer.append("-");
				areaBuffer.append(getArea(areas[1], TYPE.CITY));
				if (areas.length == 3) {
					areaBuffer.append("-");
					areaBuffer.append(getArea(areas[2], TYPE.DISTINCT));
				}
				return areaBuffer.toString();
			}
		}
		return UNKNOWN;
	}

	private Area getArea(Integer code, TYPE type) {
		return areaDao.getAreaByType(code, type);
	}
}
